package GUI.main.dialogs;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Calendar;
import java.util.GregorianCalendar;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.ListModel;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.border.MatteBorder;

import officeserver.log_error.UserException;
import officeserver.report.Appointment;
import officeserver.report.LabWork;
import officeserver.report.Treatment;
import officeserver.users.AccessLevel;
import officeserver.users.PersonalInfo;

import GUI.calendar.CalendarPanel;
import GUI.helpers.ButtonType;
import GUI.helpers.PButton;
import GUI.helpers.PTextField;
import GUI.helpers.ProjectConstants;
import GUI.helpers.TextFieldType;
import GUI.main.MainClient;
import GUI.main.renderers.TreatmentListRenderer;

/**
 * @author So-mi
 * 
 */
public class TreatmentLabWorkDialog extends JDialog implements ActionListener {
    private static final long serialVersionUID = 1L;

    private JPanel titlePanel;
    private JPanel middlePanel;

    private JPanel mainDataPanel;

    private JPanel patientPanel;
    private JLabel patientLabel;
    private PTextField patientField;

    private JPanel doctorPanel;
    private JLabel doctorLabel;
    private PTextField doctorField;

    private JPanel nursePanel;
    private JLabel nurseLabel;
    private PTextField nurseField;

    private JPanel labTypePanel;
    private JLabel labTypeLabel;
    private PTextField labTypeField;

    private JPanel datePanel;
    private JLabel dateLabel;
    private PTextField dateField;
    
    private JPanel lowerMainDataPanel;

    private JPanel instructionTitlePanel;
    private JTextArea instructionArea;

    private JPanel buttonPanel;
    private PButton closeButton;

    private static final int WIDTH = 450;
    private static final int HEIGHT = 600;
    
    private LabWork labWork;
    private Appointment appointment;

    /**
     * Creates a general format of TreatmentLabWorkDialog It's a BorderLayout
     * with North (title), Center (main data), South (close button)
     */
    public TreatmentLabWorkDialog(LabWork labWork, Appointment appointment ){
	this.labWork = labWork;
	this.appointment = appointment;
	setLayout(new BorderLayout());
	final Toolkit toolkit = Toolkit.getDefaultToolkit();
	final Dimension screenSize = toolkit.getScreenSize();
	final int x = (screenSize.width - WIDTH) / 2;
	final int y = (screenSize.height - HEIGHT) / 2;
	setLocation(x, y);
	setSize(new Dimension(WIDTH, HEIGHT));
	add(getTitlePanel(), BorderLayout.NORTH);
	add(getMiddlePanel(), BorderLayout.CENTER);
	add(getButtonPanel(), BorderLayout.SOUTH);
    }

    /**
     * Creates the bar at the top with the name of what the panel is
     * 
     * @return Text that says "Treatments" at the top
     */
    private JPanel getTitlePanel() {
	if (titlePanel == null) {
	    titlePanel = new JPanel() {
		private static final long serialVersionUID = 1L;

		public void paintComponent(Graphics g) {
		    super.paintComponent(g);
		    g.setColor(ProjectConstants.SUBHEADER_COLOR);
		    g.fillRect(0, 0, getWidth(), getHeight());
		    g.setColor(Color.white);
		    g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 24));
		    g.drawString("lab work: ", 10, getHeight() - 8);
		}
	    };
	    titlePanel.setPreferredSize(new Dimension(WIDTH,
		    ProjectConstants.HEADER_HEIGHT));
	}
	return titlePanel;
    }

    /**
     * Creates and contains the main information regarding the labwork
     */
    private JPanel getMiddlePanel() {
	if (middlePanel == null) {
	    middlePanel = new JPanel();
	    middlePanel.setLayout(new BorderLayout());

	    middlePanel.add(getMainData(), BorderLayout.NORTH);
	    middlePanel.add(getLowerMainDataPanel(), BorderLayout.CENTER);
	}
	return middlePanel;
    }

    /**
     * Creates the panel of main data
     * 
     * @return
     */
    private JPanel getMainData() {
	if (mainDataPanel == null) {
	    mainDataPanel = new JPanel();
	    mainDataPanel.setLayout(new BoxLayout(mainDataPanel,
		    BoxLayout.PAGE_AXIS));

	    mainDataPanel.add(getPatientPanel());
	    mainDataPanel.add(getDoctorPanel());
	    mainDataPanel.add(getNursePanel());
	    mainDataPanel.add(getLabTypePanel());
	    mainDataPanel.add(getDatePanel());
	}
	return mainDataPanel;
    }

    /**
     * Creates the panel of Patient data
     * 
     * @return patient info panel
     */
    private JPanel getPatientPanel() {
	if (patientPanel == null) {
	    patientPanel = new JPanel();
	    patientPanel.setBorder(new EmptyBorder(10, 10, 0, 10));
	    patientPanel.setLayout(new BorderLayout());
	    patientPanel.add(getPatientLabel(), BorderLayout.WEST);
	    patientPanel.add(getPatientField(), BorderLayout.CENTER);
	}
	return patientPanel;
    }

    /**
     * Creates the label that says "patient"
     * 
     * @return Label that says "patient"
     */
    private JLabel getPatientLabel() {
	if (patientLabel == null) {
	    patientLabel = new JLabel(ProjectConstants.CELLPAD + "patient:");
	    patientLabel.setPreferredSize(new Dimension(
		    ProjectConstants.LABEL_WIDTH_A, 25));
	}
	return patientLabel;
    }

    /**
     * Creates the PTextField that should have the patient's name
     * 
     * @return TextField with the patient's name
     */
    private PTextField getPatientField() {
	if (patientField == null) {
	    patientField = new PTextField(labWork.getPatient(), TextFieldType.LONG);
	    patientField.setEditable(false);
	}
	return patientField;
    }

    /**
     * Creates the JPanel that has stuff about the doctor
     * 
     * @return Panel with doctor information
     */
    private JPanel getDoctorPanel() {
	if (doctorPanel == null) {
	    doctorPanel = new JPanel();
	    doctorPanel.setBorder(new EmptyBorder(10, 10, 0, 10));
	    doctorPanel.setLayout(new BorderLayout());
	    doctorPanel.add(getDoctorLabel(), BorderLayout.WEST);
	    doctorPanel.add(getDoctorField(), BorderLayout.CENTER);
	}
	return doctorPanel;
    }

    /**
     * Creates the JLabel that says "Doctor"
     * 
     * @return JLabel that says "doctor"
     */
    private JLabel getDoctorLabel() {
	if (doctorLabel == null) {
	    doctorLabel = new JLabel(ProjectConstants.CELLPAD + "doctor:");
	    doctorLabel.setPreferredSize(new Dimension(
		    ProjectConstants.LABEL_WIDTH_A, 25));
	}
	return doctorLabel;
    }

    /**
     * Creates a PTextField that has the doctor's name
     * 
     * @return PTextField of doctor's name (uneditable)
     */
    private PTextField getDoctorField() {
	if (doctorField == null) {
	    doctorField = new PTextField(labWork.getDoctor(), TextFieldType.LONG);
	    doctorField.setEditable(false);
	}
	return doctorField;
    }

    /**
     * Creates a JPanel with the nurse information
     * 
     * @return
     */
    private JPanel getNursePanel() {
	if (nursePanel == null) {
	    nursePanel = new JPanel();
	    nursePanel.setBorder(new EmptyBorder(10, 10, 0, 10));
	    nursePanel.setLayout(new BorderLayout());
	    nursePanel.add(getNurseLabel(), BorderLayout.WEST);
	    nursePanel.add(getNurseField(), BorderLayout.CENTER);
	}
	return nursePanel;
    }

    /**
     * Creates a JLabel that says "Nurse"
     * 
     * @return JLabel that says "nurse"
     */
    private JLabel getNurseLabel() {
	if (nurseLabel == null) {
	    nurseLabel = new JLabel(ProjectConstants.CELLPAD + "nurse:");
	    nurseLabel.setPreferredSize(new Dimension(
		    ProjectConstants.LABEL_WIDTH_A, 25));
	}
	return nurseLabel;
    }

    /**
     * Creates a PTextField that has the nurse's name
     * 
     * @return PTextField that has the nurse's name (uneditable)
     */
    private PTextField getNurseField() {
	if (nurseField == null) {
	    nurseField = new PTextField(labWork.getNurse(), TextFieldType.LONG);
	    nurseField.setEditable(false);
	}
	return nurseField;
    }

    private JPanel getLabTypePanel() {
	if (labTypePanel == null) {
	    labTypePanel = new JPanel();
	    labTypePanel.setBorder(new EmptyBorder(10, 10, 0, 10));
	    labTypePanel.setLayout(new BorderLayout());
	    labTypePanel.add(getLabTypeLabel(), BorderLayout.WEST);
	    labTypePanel.add(getLabTypeField(), BorderLayout.CENTER);
	}
	return labTypePanel;
    }

    private JLabel getLabTypeLabel() {
	if(labTypeLabel == null){
	    labTypeLabel = new JLabel(ProjectConstants.CELLPAD + "type:");
	    labTypeLabel.setPreferredSize(new Dimension(
		    ProjectConstants.LABEL_WIDTH_A, 25));
	}
	return labTypeLabel;
    }
    
    private PTextField getLabTypeField(){
	if(labTypeField == null){
	    labTypeField = new PTextField(labWork.getType(), TextFieldType.LONG);
	    labTypeField.setEditable(false);   
	}
	return labTypeField;
    }
    
    private JPanel getDatePanel() {
	if (datePanel == null) {
	    datePanel = new JPanel();
	    datePanel.setBorder(new EmptyBorder(10, 10, 10, 10));
	    datePanel.setLayout(new BorderLayout());
	    datePanel.add(getDateLabel(), BorderLayout.WEST);
	    datePanel.add(getDateField(), BorderLayout.CENTER);
	}
	return datePanel;
    }

    private JLabel getDateLabel() {
	if(dateLabel == null){
	    dateLabel = new JLabel(ProjectConstants.CELLPAD + "date:");
	    dateLabel.setPreferredSize(new Dimension(
		    ProjectConstants.LABEL_WIDTH_A, 25));
	}
	return dateLabel;
    }
    
    private PTextField getDateField(){
	if(dateField == null){
	    appointment.getDay();
	    GregorianCalendar gc = new GregorianCalendar(2011, 0, 1);
	    gc.roll(Calendar.DAY_OF_YEAR, appointment.getDay());
	    StringBuilder builder = new StringBuilder();
	    builder.append(CalendarPanel.getMonthMap().get(
		    gc.get(Calendar.MONTH)));
	    builder.append(" ");
	    builder.append(gc.get(Calendar.DAY_OF_MONTH));
	    builder.append(", ");
	    builder.append(gc.get(Calendar.YEAR));
	    dateField = new PTextField(builder.toString(), TextFieldType.LONG);
	    dateField.setEditable(false);
	}
	return dateField;
    }
    
    /**
     * Grabs the lower part of the mainData Panel that has the instructions
     * 
     * @return
     */
    private JPanel getLowerMainDataPanel() {
	if (lowerMainDataPanel == null) {
	    lowerMainDataPanel = new JPanel();
	    lowerMainDataPanel.setBorder(new EmptyBorder(10,10,10,10));
	    lowerMainDataPanel.setLayout(new BoxLayout(lowerMainDataPanel,
		    BoxLayout.PAGE_AXIS));

	    lowerMainDataPanel.add(getInstructionTitlePanel());
	    lowerMainDataPanel.add(getInstructionField());
	}
	return lowerMainDataPanel;
    }

    /**
     * Creates a JLabel that says "instructions"
     * 
     * @return JLabel that says "instructions"
     */
    private JPanel getInstructionTitlePanel() {
	if (instructionTitlePanel == null) {
	    instructionTitlePanel = new JPanel(){
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		public void paintComponent(Graphics g){
		    super.paintComponent(g);
		    g.setColor(ProjectConstants.SUBHEADER_COLOR);
		    g.fillRect(0, 0, getWidth(), getHeight());
		    g.setColor(Color.white);
		    g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 14));
		    g.drawString("instructions: ", 10, getHeight() - 8); 
		}
	    };
	    instructionTitlePanel.setPreferredSize(new Dimension(WIDTH,50));
	}
	return instructionTitlePanel;
    }

    private JTextArea getInstructionField() {
	if (instructionArea == null) {
	    instructionArea = new JTextArea("Instructions goes here");
	    for(Treatment t : appointment.getReport().getTreatments()){
		if(t.getTID() == labWork.getTID()){
		    instructionArea.setText(t.getInstructions());
		}
	    }
	    instructionArea.setBorder(new EmptyBorder(20, 20, 20, 20));
	    instructionArea.setEditable(false);
	}
	return instructionArea;
    }

    /**
     * creates the "close" button at the bottom.
     * 
     * @return the panel containing the close button
     */
    private JPanel getButtonPanel() {
	if (buttonPanel == null) {
	    buttonPanel = new JPanel();

	    buttonPanel.setBorder(new EmptyBorder(10, 10, 10, 10));

	    buttonPanel.add(getCloseButton());
	}
	return buttonPanel;
    }

    /**
     * Gives the actual "close" button for the bottom
     * 
     * @return the close button
     */
    private PButton getCloseButton() {
	if (closeButton == null) {
	    closeButton = new PButton("Close", ButtonType.MEDIUM);
	    closeButton.addActionListener(this);
	}
	return closeButton;
    }


    @Override
    public void actionPerformed(ActionEvent e) {
	if(e.getSource() == getCloseButton()){
	    this.setVisible(false);
	}
    }

}
